package cuppics;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.junit.Test;

public class Prj3 {

	@Test
	public void test() {
		{
			IntegerDivisor div = new IntegerDivisor();
			div.divisor(600851475143L);
			System.out.println(div);
		}
		{
			IntegerDivisor div = new IntegerDivisor();
			div.divisor(100001);
			System.out.println(div);
		}
		{
			IntegerDivisor div = new IntegerDivisor();
			div.divisor(10010);
			System.out.println(div);
		}
		{
			IntegerDivisor div = new IntegerDivisor();
			div.divisor(1100);
			System.out.println(div);
		}

		System.out.println(new CalculateMaxPrime(20).calculate());
	}

	public static class IntegerDivisor {

		public Map<Long, Integer> primeMap = new HashMap<Long, Integer>();
		public List<Long> primeList = new ArrayList<Long>();

		public void divisor(long num) {

			if (num <= 1)
				return;

			long prime = getPrime(
					num,
					primeList.size() == 0 ? 2
							: primeList.get(primeList.size() - 1));
			if (prime < 0) {
				primeMap.put(num, 1);
				primeList.add(num);
				return;
			} else {

				primeList.add(prime);
				int count = 0;
				do {

					count += 1;
					num = num / prime;
				} while (num % prime == 0);

				primeMap.put(prime, count);

				divisor(num);

			}

		}

		private long getPrime(long num, long start) {

			for (long i = start; i <= Math.sqrt(num); i++) {
				if (num % i == 0) {
					return i;
				}
			}
			return -1;
		}

		@Override
		public String toString() {

			StringBuilder sb = new StringBuilder();
			for (Entry<Long, Integer> entry : primeMap.entrySet()) {
				sb.append(entry.getKey().toString() + "="
						+ entry.getValue().toString() + "\n");
			}

			for (int i = 0; i < primeList.size(); i++) {
				sb.append(primeList.get(i) + "--->");
			}
			return sb.toString();
		}

		public Long getLargestPrime() {
			return primeList.get(primeList.size() - 1);
		}

	}

}

class CalculateMaxPrime {

	private int num;

	public CalculateMaxPrime(int num) {
		this.num = num;

	}

	public int calculate() {

		for (int i = num - 1; i >= 2; i--) {
			if (isPrime(i) && num % i == 0) {
				return i;
			}
		}

		return num;
	}

	private boolean isPrime(int val) {

		for (int i = 2; i <= Math.sqrt(val); i++) {
			if (val % i == 0) {
				return false;
			}
		}

		return true;
	}

}
